package com.david.http.http.convert

import kotlinx.coroutines.flow.Flow
import retrofit2.CallAdapter
import retrofit2.Response
import retrofit2.Retrofit
import java.io.IOException
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

class FlowCallAdapterFactory private constructor() : CallAdapter.Factory() {
    override fun get(
        returnType: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        val rawType = getRawType(returnType)
        return if (rawType == Flow::class.java) {
            if (returnType !is ParameterizedType) {
                throw IOException("Flow must be parameterized as Flow<Foo>")
            }
            val type = getResponseType(returnType) ?: throw IOException("get response type failed")
            ResponseCallAdapter(type)
        } else {
            null
        }
    }

    private fun getResponseType(returnType: Type): Type? {
        val type = returnType as? ParameterizedType ?: return null
        return getParameterUpperBound(0, type)
    }

    companion object {
        @JvmStatic
        fun create() = FlowCallAdapterFactory()
    }
}